Installieren von R

In diesem Kurs wird mit der Sprache R gearbeitet. R wird bereits mit einer rudimentären grafischen Benutzer:innenoberfläche geliefert. Ich rate deutlich davon ab, sich auf diese zu beschränken. Durch das Nutzen von RStudio wird das Arbeiten mit R deutlich Benutzer:innenfreundlicher.

  1. R Installieren https://cran.r-project.org/ aufrufen Betriebssystem wählen Neuste R Version downloaden und installieren
  1. RStudio installieren https://www.rstudio.com/products/rstudio/download/#download aufrufen Free version auswählen Betriebssystem auswählen RStudio installieren

Einführung in R

Es ist möglich jegliche Berechnung, die in einem Taschenrechner möglich sind auch in r auszuführen.

1+2
## [1] 3
1-2
## [1] -1
2*2
## [1] 4
6/2
## [1] 3
2^2
## [1] 4

Auf diese Ergebnisse lässt sich jedoch nicht zugreifen, da sie nicht gespeichert wurden. Durch <- werden Berechnungen einem Objekt zugeordnet und dieses ggf. erstellt. Mit diesen Objekten können dann weiter Berechnungen durchgeführt werden.

a <- 3*5
a
## [1] 15
b <- 4-2

a* b
## [1] 30

Die erstellten Objekte sind veränderlich.

a <- a* b -6 + (2*4)
a
## [1] 32

In der Praxis wird empfohlen, den Objekten aussagekräftige Namen zu geben. Sodass, auch bei späteren Betrachtungen, der Code verständlich bleibt. Da zwischen Groß- und Kleinschreibung unterschieden wird, empfehle ich nur Kleinschreibung zu verwenden, um Verwirrungen zu vermeiden. Den die Objekte Mittelwert und mittelwert sind zwei verschiedene Objekte.

mittelwert <- (1+2+3+4+5+6)/6
Mittwelwert <- (5+6+7+8) / 4

Funktionen

Führt man eine Operation öfter durch, ist es manchmal sinnvolle eine Funktion im Vorhinein zu definieren, um dann später darauf zuzugreifen.

word_printer <- function(word){
                              print(paste('Dies ist ein Wort:', word ))
                            }

word_printer('hallo')
## [1] "Dies ist ein Wort: hallo"

Datenstrukturen

Objekte können verschiedenen Klassen angehören. Nicht mit jeder Klasse lässt sich jeder Befehl ausführen. Dies ist auch sinnvoll, da in der Ursprungsform das Rechen mit Buchstaben nicht möglich ist.

text <- "Mittwoch ist Spritwoch"
class(text)
## [1] "character"
zahl <- 1
class(zahl)
## [1] "numeric"
zahl <- "1"
class(zahl)
## [1] "character"
zahl <- 1.1
class(zahl)
## [1] "numeric"
date <- as.Date("2020-05-05")
class(date)
## [1] "Date"
x <- "apfel" == "birnen"
x
## [1] FALSE
class(x)
## [1] "logical"

Vektoren

Objekte können jedoch auch mehrere Werte enthalten. Um verschiedene Möglichkeiten der Komplexität zu haben, gibt es verschiedene Datenstrukturen. Bei Vektoren handelt es sich um eindimensionale Reihen von Ausprägungen (aus der Schule bekannt). Die Klasse der Ausprägungen müssen jedoch gleich bleiben sein. Eine Liste hingegen kann verschieden Klassen enthalten. In zwei Dimensionen entspricht der Vektor der Matrix und das Dataframe der Liste. Dataframes können auch mehr als zwei Auf Twitter teilenDimensionen haben, werden jedoch dann Tensor genannt. Auf Ausprägungen in jeder Datenstruktur kann auch einzeln zugegriffen werden.

vektor_zahlen <- c(1,2,3,4,5)

vektor_zahlen
## [1] 1 2 3 4 5
vektor_text <- c("Dumbledore", "Rubeus Hagrid", "Minerva McGonagall")
vektor_text
## [1] "Dumbledore"         "Rubeus Hagrid"      "Minerva McGonagall"
vektor_text[1]
## [1] "Dumbledore"
vektor_text[c(1,2)]
## [1] "Dumbledore"    "Rubeus Hagrid"

Mit Vektoren können auch Berechnungen durchgeführt werden bzw. die Vektoren als Input in Funktionen gegeben werden. Praktische Funktionen für Vektoren sind beispielsweise mean(), length(), sum() und sd(). Informationen über Funktionen aus Paketen können über ?mean() aufegrufen werden.

vektor_zahlen_2 <- c(8,9,0,23,3)

vektor_zahlen * vektor_zahlen_2
## [1]  8 18  0 92 15
mean(vektor_zahlen)
## [1] 3
length(vektor_zahlen * vektor_zahlen_2)
## [1] 5
sum(vektor_zahlen * vektor_zahlen_2)
## [1] 133
sd(vektor_zahlen_2)
## [1] 8.848729

Listen

Listen können verschiedene Klassen von Daten enthalten. Beispielsweise ist die Kombination von character und numeric Klasse möglich. Grundsätzlich können Listen verschiedenste Formate enthalten, z. B. zum Beispiel auch Vektoren oder sogar auch andere Listen. Wenn den Variablen Namen zugewiesen werden, kann auf diese über die $ Option direkt auf die Variabel zugegriffen werden. Wie bereits zuvor ist das Zugreifen über die [] ebenfalls möglich.

mitarbeiter <- list(name = "Dumbledore", "Rubeus Hagrid", "Minerva McGonagall", ort ="hogwarts", Land = "uk",  postleitzahl = 48151 )
mitarbeiter
## $name
## [1] "Dumbledore"
## 
## [[2]]
## [1] "Rubeus Hagrid"
## 
## [[3]]
## [1] "Minerva McGonagall"
## 
## $ort
## [1] "hogwarts"
## 
## $Land
## [1] "uk"
## 
## $postleitzahl
## [1] 48151
mitarbeiter$name
## [1] "Dumbledore"
mitarbeiter[1]
## $name
## [1] "Dumbledore"
mitarbeiter[[2]]
## [1] "Rubeus Hagrid"
mitarbeiter[2]
## [[1]]
## [1] "Rubeus Hagrid"

Matrizen

Bei Matrizen handelt es um die zweidimensionale äquivalent zum Vektor. Ein zugreifen über den $ Operator ist nicht möglich. Jedoch weiterhin über die []. Wobei die [,1] der ersten Spalte und [1, ] der ersten Zeile entspricht. [2,1] ist dann die erste Zelle in der ersten Spalte in der zweiten Zeile.

x <- 1:9
m <- matrix(x, nrow = 3)
m
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
colnames(m) <- c("eins", "zwei", "drei")
rownames(m)<- c("eins", "zwei", "drei")
m
##      eins zwei drei
## eins    1    4    7
## zwei    2    5    8
## drei    3    6    9
m[,2]
## eins zwei drei 
##    4    5    6

Dataframe

Bei Dataframes handelt es sich um das meist genutzten Datenformat. Wie bei den Listen kann auf Dataframes direkt auf die Spalten/Variablen über $ zugegriffen werden. Auch können verschiedene Klassen gespeichert werden.

hogwarts_mitarbeiter <- data.frame(
  name = c("Dumbledore", "Rubeus Hagrid", "Minerva McGonagall", "Severus Snape"),
  beruf = c("Schulleiter", "Wildhüter", "Lehrer_in", "Lehrer_in"),
  alter = c(102, 54, 65, 55)
)

hogwarts_mitarbeiter 
##                 name       beruf alter
## 1         Dumbledore Schulleiter   102
## 2      Rubeus Hagrid   Wildhüter    54
## 3 Minerva McGonagall   Lehrer_in    65
## 4      Severus Snape   Lehrer_in    55
hogwarts_mitarbeiter[2,2]
## [1] "Wildhüter"
hogwarts_mitarbeiter[2,1:3]
##            name     beruf alter
## 2 Rubeus Hagrid Wildhüter    54
hogwarts_mitarbeiter$name
## [1] "Dumbledore"         "Rubeus Hagrid"      "Minerva McGonagall"
## [4] "Severus Snape"
hogwarts_mitarbeiter$beruf[1]
## [1] "Schulleiter"

Grundsätzlich ist es empfehlenswert, zu Beginn einer Analyse eine Übersicht über die Daten zu erhalten. Dies ist z. B. durch die Funktion str() zu erreichen. Für jede Variabel wird die Klasse und die ersten Ausprägungen dargestellt.

str(hogwarts_mitarbeiter)
## 'data.frame':    4 obs. of  3 variables:
##  $ name : chr  "Dumbledore" "Rubeus Hagrid" "Minerva McGonagall" "Severus Snape"
##  $ beruf: chr  "Schulleiter" "Wildhüter" "Lehrer_in" "Lehrer_in"
##  $ alter: num  102 54 65 55

Eine weitere praktische Funktion um einen Überblick zu erhalten ist die Funktion Summary(). Auch hier erhält, wird die Klasse pro Variable dargestellt. Für numerische Variablen erhält man weiterhin Informationen über die Verteilung.

summary(hogwarts_mitarbeiter)
##      name              beruf               alter       
##  Length:4           Length:4           Min.   : 54.00  
##  Class :character   Class :character   1st Qu.: 54.75  
##  Mode  :character   Mode  :character   Median : 60.00  
##                                        Mean   : 69.00  
##                                        3rd Qu.: 74.25  
##                                        Max.   :102.00

Durch head() ist es möglich nur eine gewisse Anzahl von Zeilen auszugeben.

head(hogwarts_mitarbeiter,5)
##                 name       beruf alter
## 1         Dumbledore Schulleiter   102
## 2      Rubeus Hagrid   Wildhüter    54
## 3 Minerva McGonagall   Lehrer_in    65
## 4      Severus Snape   Lehrer_in    55

Die Funktion mean() in Kombination mit der Auswahl einer numerischen Variable bestimmt den Durchschnitt

mean(hogwarts_mitarbeiter$alter)
## [1] 69

Durch Subset() können Dataframes in Base r gefiltert werden. In diesem Beispiel werden alle Zeilen ausgeben, in denen der Name nicht Dumbledore ist.

subset(hogwarts_mitarbeiter, name != "Dumbledore")
##                 name     beruf alter
## 2      Rubeus Hagrid Wildhüter    54
## 3 Minerva McGonagall Lehrer_in    65
## 4      Severus Snape Lehrer_in    55

Packages

Bereits Base R bietet viele Funktionen und Möglichkeiten. Die besondere Power von R kommt jedoch durch die hohe Anzahl an verschieden Packages, die den Funktionsumfang deutlich erweitern. Packages können von jeden erstellt werden. Bevor diese jedoch über CRAN (install.packages) heruntergeladen werden können, hat eine andere freiwillige Person dieses überprüft. Packages können auch abseits von CRAN installiert werden. Hier ist jedoch Vorsicht geboten, da unklar sein kann, was dieses Paket enthält (Viren).

install.packages("tidyverse")
library()

Packages müssen nur einmal in dem entsprechenden Environment installiert werden. Bevor das Packages jedoch nutzbar ist, muss es pro Session per library(tidyverse) aktiviert werden.

library(tidyverse)

Tidyverse bietet viele verschiedene Funktionen zum Arbeiten mit Daten. Neben diesen Funktionen kommt mit Tidyverse auch die Möglichkeit einer anderen Syntax -Konzept zu nutzen. Hierbei spielt der Pipe-Operatur %>% die entscheidende Rolle. Durch %>% können Argumente und Daten auf einfache Weise an die nächste Funktion übergeben werden und erleichter deutlich das Arbeiten und Lesen von RCode. Durch %>% werden hier beispielsweise die daten aus dem Dataframe an die Funktion filter übergeben. DieDaten werden auf alle Zeilen gefiltert, die in der Variable name die Ausprägung Dumbledore haben.

hogwarts_mitarbeiter %>%  filter( name == "Dumbledore")
##         name       beruf alter
## 1 Dumbledore Schulleiter   102

Durch die Funktion group_by werden die Daten anhand des Inputs gruppiert. Group_by erfordert eine weitere Funktion, in der die Berechnungsart pro Gruppe definiert werden muss. Hier gibt es unzählige Möglichkeiten. In diesem Beispiel wird die Anzahl der Ausprägungen pro Gruppe gezählt.

hogwarts_mitarbeiter %>%  group_by(beruf) %>% count()
## # A tibble: 3 x 2
## # Groups:   beruf [3]
##   beruf           n
##   <chr>       <int>
## 1 Lehrer_in       2
## 2 Schulleiter     1
## 3 Wildhüter       1

Besonders mächtig in Kombination mit Group_by ist die Funktion summarise. In dieser Funktion kann die Operation, die pro Gruppe durchgeführt wird, manuell definiert werden. In diesem Beispiel wird für jede Gruppe der gruppenspezifische Mittelwert berechnet.

hogwarts_mitarbeiter %>%  group_by(beruf) %>% summarise(d_alter = mean(alter))
## # A tibble: 3 x 2
##   beruf       d_alter
##   <chr>         <dbl>
## 1 Lehrer_in        60
## 2 Schulleiter     102
## 3 Wildhüter        54

Loops

For-Loop

In For-Loops wird über ein zu definierendes Element iteriert. So kann für jedes beispielsweise für jede Zeile in einem Dataframe eine Berechnung durchgeführt werden.

for (i in 1:10){
  print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10

While-Loop

In einem While-Loop wird die Funktion innerhalb des Loops so lange iterativ durchgeführt, bis die in While definierte Bedingung nicht mehr erfüllt ist.

i <- 1
while (i < 6) {
  print(i)
  i = i+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5

Einlesen der Daten für die Hausarbeit

Bundestag

#Laden Library
library(plotly)
library(dplyr)
library(jsonlite)


# Laden der Bundestag Daten
filename <- file.choose()
Bundestag <- readRDS(filename)



# Erste fünf Zeilen sehen
#View(head(Bundestag))

# Ãueberblick
str(Bundestag)
## 'data.frame':    379545 obs. of  11 variables:
##  $ date          : chr  "1991-03-12" "1991-03-12" "1991-03-12" "1991-03-12" ...
##  $ agenda        : chr  NA NA NA NA ...
##  $ speechnumber  : chr  "2" "3" "4" "5" ...
##  $ speaker       : chr  "Theodor Waigel" "Rita Süssmuth" "Theodor Waigel" "Rita Süssmuth" ...
##  $ party         : chr  "CDU/CSU" "CDU/CSU" "CDU/CSU" "CDU/CSU" ...
##  $ party.facts.id: num  211 211 211 211 86 211 211 211 383 211 ...
##  $ chair         : logi  FALSE TRUE FALSE TRUE FALSE TRUE ...
##  $ terms         : num  880 15 5756 69 233 ...
##  $ text          : chr  "Frau Präsidentin ! Meine sehr geehrten Damen und Herren ! Der Ihnen heute zur ersten Beratung vorliegende Entwu"| __truncated__ "Herr Duve , ich fordere Sie auf , Herrn Waigel reden zu lassen . ." "Nicht viel besser sieht es im Straßenwesen aus . Auch das früher vorbildliche S- und U-Bahn-System Berlins ist "| __truncated__ "Meine Damen und Herren , wie bereits heute morgen mitgeteilt , kommen wir jetzt zur Beratung und Abstimmung übe"| __truncated__ ...
##  $ parliament    : chr  "DE-Bundestag" "DE-Bundestag" "DE-Bundestag" "DE-Bundestag" ...
##  $ iso3country   : chr  "DEU" "DEU" "DEU" "DEU" ...
summary(Bundestag)
##      date              agenda          speechnumber         speaker         
##  Length:379545      Length:379545      Length:379545      Length:379545     
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##                                                                             
##     party           party.facts.id     chair             terms        
##  Length:379545      Min.   :  86.0   Mode :logical   Min.   :    1.0  
##  Class :character   1st Qu.: 211.0   FALSE:212460    1st Qu.:   11.0  
##  Mode  :character   Median : 383.0   TRUE :167085    Median :   57.0  
##                     Mean   : 607.8                   Mean   :  290.5  
##                     3rd Qu.: 573.0                   3rd Qu.:  406.0  
##                     Max.   :1976.0                   Max.   :17202.0  
##                     NA's   :71981                                     
##      text            parliament        iso3country       
##  Length:379545      Length:379545      Length:379545     
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
##                                                          
## 
# Filtern der Daten nach Partein. Anschliessend nach Parteien gruppieren und die Anzahl der Reden zählen
party_speech <- Bundestag %>% filter(party !=   'NA' & date >= '2017-01-01' ) %>% group_by(party)  %>% count()



# Definieren der Farben - Parteifarben
colors <- c('rgb(139,69,19)', 'rgb(0,0,0)', 'rgb(255,237,0)', 'rgb(100,161,45)', 'rgb(255, 255, 255)', 'rgb(104,34,139)'  ,'rgb(227, 0, 15)')


# Plotly
fig <- plot_ly(party_speech, labels = ~party, values = ~n, type = 'pie',

               textposition = 'inside',

               textinfo = 'label+percent',

               insidetextfont = list(color = '#FFFFFF'),

               hoverinfo = 'text',

               text = ~paste( n, ' Reden'),

               marker = list(colors = colors,

                             line = list(color = '#FFFFFF', width = 1)),

               showlegend = FALSE)

# Layout
fig <- fig %>% layout(title = 'Verteilung der Reden nach Partei seit 2017',

                      xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),

                      yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))

# Ausführen
fig

Kreml Data

setwd('C:\\Users\\Drecker\\Documents\\Lehre')
# load data
kreml <- lapply(readLines(".\\Daten\\kremlin_transcripts_en_2021_03_01.json"), fromJSON)


# Umwandeln von List in List zu dataframe
kreml_data <- data.frame(id = as.integer(), date = as.character(), title = as.character(), text = as.character())
for (i in 1:length(kreml)){

  doc <- data.frame(id = kreml[[i]]$`_source`$kremlin_id, date = kreml[[i]]$`_source`$date, title = kreml[[i]]$`_source`$title, text = kreml[[i]]$`_source`$transcript)
  kreml_data <- bind_rows(kreml_data, doc )
}

# Erstellen einer Day Spalte
kreml_data <- kreml_data %>% mutate(weekday = weekdays(as.Date(kreml_data$date)) )

# Group by weekday
plot_data <-kreml_data %>%
            group_by(weekday) %>%
            count()

# Ãndern des weekdays auf factor um anschlieÃssend die Tage ordnen zu können
# Wenn dieser Schritt nicht durchgeführt wird werden die Tage nach Alphabet geordnet
plot_data$weekday<- factor(plot_data$weekday, levels= c( "Montag",
                                         "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag","Sonntag"))
plot_data <- plot_data %>% arrange(weekday)

  plot_ly(
  x = plot_data$weekday,
  y = plot_data$n,
  name = "",
  type = "bar"
)

Sentiment Data

setwd('C:\\Users\\Drecker\\Documents\\Lehre')
sen_train <-   read.csv(file = ".\\Daten\\Sentiment\\Corona_NLP_train.csv")  
sen_test <-   read.csv(file = ".\\Daten\\Sentiment\\Corona_NLP_test.csv")  


train_stat <- sen_train %>% group_by(Sentiment)  %>% 
  summarise(Anzahl = n(), Anteil = n()/ sen_train %>% group_by(Sentiment) %>% count() %>% ungroup(Sentiment) %>% summarise('Other'=sum(n)))

train_stat 
## # A tibble: 5 x 3
##   Sentiment          Anzahl Anteil$Other
##   <chr>               <int>        <dbl>
## 1 Extremely Negative   5481        0.133
## 2 Extremely Positive   6624        0.161
## 3 Negative             9917        0.241
## 4 Neutral              7713        0.187
## 5 Positive            11422        0.278
test_stat <- sen_test  %>% group_by(Sentiment)  %>% 
  summarise(Anzahl = n(), Anteil = n()/ sen_test %>% group_by(Sentiment) %>% count() %>% ungroup(Sentiment) %>% summarise('Other'=sum(n)))

test_stat 
## # A tibble: 5 x 3
##   Sentiment          Anzahl Anteil$Other
##   <chr>               <int>        <dbl>
## 1 Extremely Negative    592        0.156
## 2 Extremely Positive    599        0.158
## 3 Negative             1041        0.274
## 4 Neutral               619        0.163
## 5 Positive              947        0.249

Fakenews Data

setwd('C:\\Users\\Drecker\\Documents\\Lehre')
  
fake <-   read.csv(file = ".\\Daten\\Fakenews_detection\\Fake.csv")  
true <-   read.csv(file = ".\\Daten\\Fakenews_detection\\True.csv")  

head(true[1])
##                                                                   title
## 1      As U.S. budget fight looms, Republicans flip their fiscal script
## 2      U.S. military to accept transgender recruits on Monday: Pentagon
## 3          Senior U.S. Republican senator: 'Let Mr. Mueller do his job'
## 4           FBI Russia probe helped by Australian diplomat tip-off: NYT
## 5 Trump wants Postal Service to charge 'much more' for Amazon shipments
## 6      White House, Congress prepare for talks on spending, immigration